/*
 * uart.h
 *
 *  Created on: Aug 3, 2013
 *      Author: Ken Arok
 *
 * \brief Hardware Abstraction Layer of UART Controller UC3C0512C
 *
 * Copyright (c) 2013 PT Hanindo Automation Solutions. All rights reserved.
 *
 */

#include "config_board.h"

#if BOARD_1_0_USED

#ifndef UART_H_
#define UART_H_

#include <stdint.h>
#include <stdbool.h>
#include <avr32/io.h>

#ifdef __cplusplus
extern "C" {
#endif


/* Default time-out value (number of attempts). */
#define UART_DEFAULT_TIMEOUT         10000
#define UART_RECEIVE_TIMEOUT		  5000

/* Default time guard. */
#define UART_DEFAULT_TIMEGUARD		4

/*! \name Parity Settings
 */
//! @{
#define UART_EVEN_PARITY             AVR32_USART_MR_PAR_EVEN   //!< Use even parity on character transmission.
#define UART_ODD_PARITY              AVR32_USART_MR_PAR_ODD    //!< Use odd parity on character transmission.
#define UART_SPACE_PARITY            AVR32_USART_MR_PAR_SPACE  //!< Use a space as parity bit.
#define UART_MARK_PARITY             AVR32_USART_MR_PAR_MARK   //!< Use a mark as parity bit.
#define UART_NO_PARITY               AVR32_USART_MR_PAR_NONE   //!< Don't use a parity bit.
#define UART_MULTIDROP_PARITY        AVR32_USART_MR_PAR_MULTI  //!< Parity bit is used to flag address characters.
//! @}

/*! \name Stop Bits Settings
 */
//! @{
#define UART_1_STOPBIT               AVR32_USART_MR_NBSTOP_1   //!< Use 1 stop bit.
#define UART_1_5_STOPBITS            AVR32_USART_MR_NBSTOP_1_5 //!< Use 1.5 stop bits.
#define UART_2_STOPBITS              AVR32_USART_MR_NBSTOP_2   //!< Use 2 stop bits (for more, just give the number of bits).
//! @}

/*! \name Channel Modes
 */
//! @{
#define UART_NORMAL_CHMODE           AVR32_USART_MR_CHMODE_NORMAL      //!< Normal communication.
#define UART_AUTO_ECHO               AVR32_USART_MR_CHMODE_ECHO        //!< Echo data.
#define UART_LOCAL_LOOPBACK          AVR32_USART_MR_CHMODE_LOCAL_LOOP  //!< Local loopback.
#define UART_REMOTE_LOOPBACK         AVR32_USART_MR_CHMODE_REMOTE_LOOP //!< Remote loopback.
//! @}

/** \name UART Status.
 */
//! @{
#define UART_STATUS_OK				0	//!< Success
#define UART_ERR_IO_ERROR			1	//!< I/O error
#define UART_ERR_FLUSHED			2	//!< Request flushed from queue
#define UART_ERR_TIMEOUT			3	//!< Operation timed out
#define UART_ERR_BAD_DATA			4	//!< Data integrity check failed
#define UART_ERR_PROTOCOL			5	//!< Protocol error
#define UART_ERR_UNSUPPORTED_DEV	6	//!< Unsupported device
#define UART_ERR_NO_MEMORY			7	//!< Insufficient memory
#define UART_ERR_INVALID_ARG		8	//!< Invalid argument
#define UART_ERR_BAD_ADDRESS		9	//!< Bad address
#define UART_ERR_BUSY				10	//!< Resource is busy
#define UART_ERR_BAD_FORMAT			11	//!< Data format not recognized
#define UART_ERR_PORT_NOT_READY		12	//!< Port is not ready.
#define UART_ERR_PORT_IS USED		13	//!< Port is used by other.
#define UART_OPERATION_IN_PROGRESS	128
//! @}

typedef uint8_t uart_status_code_t;

/** \name UART Transfer mode.
 */
//! @{
#define UART_POLLED_TX		1
#define UART_POLLED_RX		2
#define UART_INTERRUPT_TX	3
#define UART_INTERRUPT_RX	4
//! @}

typedef uint8_t uart_transfer_mode_flag_t;

/* COM path name */
typedef const char * COM_path;

/* Structure of SPI peripheral decriptors. */
typedef struct {
	const char *path_name;	//!< Pointer to UART Path Name
	uint8_t path_index;		//!< Index of path peripheral.
	uint8_t port_state;		//!< State of port (1 = open, 0 = close).
	uint32_t *recved_size;	//!< Actual received size for read operation.
	uint8_t transfer_mode;	//!< Transfer mode (bit 0: tx, bit 1: rx). 1 = interrupt; 0 = polled.
} uart_peripheral_descriptors_t;

/* SPI descriptor */
typedef void * com_descriptor_t;

/* Input parameters when initializing RS232 and similar modes. */
typedef struct
{
	uint32_t baudrate;			//!< Set baud rate of the UART.
	uint8_t charlength;			//!< Data width (5 to 9).
	uint8_t paritytype;			//!< Parity check.
	uint16_t stopbits;			//!< Stop bits between two characters
	uint8_t channelmode;		//!< Run the channel in testmode.
} uart_options_t;

//------------------------------------------------------------------------------

/** \brief Open the UART port.
 *
 * @param _path_name	Path name of COM port.
 * @param _flag			Flag of opening.
 * @return Pointer to peripheral description.
 */
extern com_descriptor_t uart_open(COM_path _path_name, const uint8_t _flag);

/** \brief Close the UART port.
 *
 * @param _descriptor	Pointer to peripheral descriptor.
 * @param _flag			Flag of closing port.
 * @return Status
 */
extern uart_status_code_t uart_close(com_descriptor_t _descriptor, const uint8_t _flag);

/** \brief Send a packet of word data out to serial port.
 *
 * @param _descriptor	Pointer to peripheral descriptor.
 * @param _pPacket		Pointer to the packet data want to be sent out.
 * @param _size_t		The length of packet want to be sent out.
 * @return Status
 */
extern uart_status_code_t uart_write_word(com_descriptor_t _descriptor, const void *_pPacket, uint32_t _size_t);

/** \brief Send a packet of byte data out to serial port.
 *
 * @param _descriptor	Pointer to peripheral descriptor.
 * @param _pPacket		Pointer to the packet data want to be sent out.
 * @param _size_t		The length of packet want to be sent out.
 * @return Status
 */
extern uart_status_code_t uart_write_byte(com_descriptor_t _descriptor, const void *_pPacket, uint32_t _size_t);

/** \brief Get a packet of word data from serial port.
 *
 * @param _descriptor	Pointer to peripheral descriptor.
 * @param _pRxBuff		Pointer to the buffer where the packet data will be stored.
 * @param _size_t		Number of word of data must be received.
 * @return Status
 *
 */
extern uart_status_code_t uart_read_word(com_descriptor_t _descriptor, void *_pRxBuff, uint32_t _size_t);

/** \brief Get a packet of byte data from serial port.
 *
 * @param _descriptor	Pointer to peripheral descriptor.
 * @param _pRxBuff		Pointer to the buffer where the packet data will be stored.
 * @param _size_t		Number of byte of data must be received.
 * @return Status
 *
 */
extern uart_status_code_t uart_read_byte(com_descriptor_t _descriptor, void *_pRxBuff, uint32_t _size_t);

/** \brief Initialize serial communication interface.
 */
extern void uart_init(void);

/** \brief Set UART transfer mode.
 *
 * @param _descriptor	Pointer to peripheral descriptor.
 * @param _flag			Mode flag.
 *						UART_POLLED: TX = Polled, RX = Polled.
 *						UART_POLEED_TX: TX = Polled, RX = Interrupt.
 *						UART_POLLED_RX: TX = Interrupt, RX = Polled.
 *						UART_INTERRUPT: TX = Interrupt, RX = Interrupt.
 *
 * @return Status.
 */
extern uart_status_code_t uart_tranfer_mode(com_descriptor_t _descriptor, uart_transfer_mode_flag_t _flag);


/** \brief Set timeout value to receiver.
 *
 * @param _descriptor	Pointer to peripheral descriptor.
 * @param _to_ms		Timeout value in milisecond.
 * @return Status.
 *
 */
extern uart_status_code_t uart_rx_timeout(com_descriptor_t _descriptor, const uint32_t _to_ms);

/** \brief Load UART setting from ROM.
 *
 * @param _descriptor	Pointer to peripheral descriptor.
 * @return Status.
 */
extern uart_status_code_t uart_load_setting(com_descriptor_t _descriptor);

/** \brief Test UART signal.
 *
 * @param _descriptor	Pointer to peripheral descriptor.
 * @return true if there are signaling. Otherwise false.
 */
extern bool uart_test_signal(com_descriptor_t _descriptor);

/** \brief Release UART signal.
 *
 * @param _descriptor	Pointer to peripheral descriptor.
 * @return Status.
 */
extern uart_status_code_t uart_release_signal(com_descriptor_t _descriptor);

/** \brief Set UART setting to default.
 *
 * @param _descriptor	Pointer to peripheral descriptor.
 * @return Status.
 */
extern uart_status_code_t uart_set_default(com_descriptor_t _descriptor);

/** \brief Save UART setting to ROM.
 *
 */
extern void uart_save_setting(void);

/** \brief Set UART Speed.
 *
 * @param _descriptor	Pointer to peripheral descriptor.
 * @param _baud			Desired baudrate.
 * @return Status.
 */
extern uart_status_code_t uart_set_speed(com_descriptor_t _descriptor, uint32_t _baud);

/** \brief Set UART Data Length.
 *
 * @param _descriptor	Pointer to peripheral descriptor.
 * @param _databit		Desired data length.
 * @return Status.
 */
extern uart_status_code_t uart_set_databit(com_descriptor_t _descriptor, uint8_t _databit);

/** \brief Set UART Parity.
 *
 * @param _descriptor	Pointer to peripheral descriptor.
 * @param _par			Desired parity.
 * @return Status.
 */
extern uart_status_code_t uart_set_parity(com_descriptor_t _descriptor, uint8_t _par);

/** \brief Set UART Stop Bit.
 *
 * @param _descriptor	Pointer to peripheral descriptor.
 * @param _stop			Desired stop bit.
 * @return Status.
 */
extern uart_status_code_t uart_set_stopbit(com_descriptor_t _descriptor, uint8_t _stop);

/** \brief Get Current UART Setting.
 *
 * @param _descriptor	Pointer to peripheral descriptor.
 * @return Pointer to UART options structure.
 */
extern uart_options_t *uart_get_setting(com_descriptor_t _descriptor);

#ifdef __cplusplus
}
#endif

#endif /* UART_H_ */

#endif /* BOARD_1_0_USED */
